package ios.di.logviewer.xml.parser;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;

import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

/**
 * 日志文件（XML文件）解析器，getLogNode()接口可提取出一条日志内容
 * @author LuoHouQi
 *
 */


public class LogXMLParser {
	public static final String ENCODING = "GB2312";
	private static final char[] LOG_NODE_START={'L','O','G','>'};
	private static final char[] LOG_NODE_END={'/','L','O','G','>'};
	File file;
	FileInputStream fis;
	InputStreamReader reader;
	int logNodeCount;
	
	public LogXMLParser(File file) throws FileNotFoundException, UnsupportedEncodingException {
		super();
		this.file = file;
		
		this.fis = new FileInputStream(this.file);
		this.reader = new InputStreamReader(this.fis,ENCODING);
	}
	public StringBuffer getLogNode() throws FileEndException, IOException {
		int con;
		char cha;
		int isEnd;
		StringBuffer strBu = new StringBuffer(160);
		while ((con = reader.read()) != -1) {	
			cha = (char)con;
			if (cha == '<') {
				char[] node = new char[4];
				isEnd = reader.read(node);
				if(isEnd==-1)
					throw new FileEndException();
				if (conpareCharArray(node, LOG_NODE_START)) {

					while ((cha = (char) reader.read()) != -1)
					{
						if (cha != '<')
							strBu.append(cha);
						else {
							char[] contArray = new char[5];
							isEnd = reader.read(contArray);
							if(isEnd==-1)
								throw new FileEndException();
							else if (conpareCharArray(contArray, LOG_NODE_END)) {
								logNodeCount++;
								//System.out.println(strBu.toString());
								return strBu;
							} else {
								strBu.append(cha);
								strBu.append(contArray);
							}
						}
					}
				} else {
					continue;
				}

			}

		}
		if (con == -1)
			throw new FileEndException();
		return null;
	}
	public int getPosition()
	{
		return this.logNodeCount;
	}
	public void reset(int distance) throws  IOException
	{
		reader.close();
		fis.close();
		 fis = new FileInputStream(this.file);
		 reader = new InputStreamReader(fis,ENCODING);
		int nodeIndex = 0;
		this.logNodeCount = distance;
		while(nodeIndex<distance)
		{
			
				try {
					getLogNode();
				} catch (FileEndException e) {
					break;
				}
			
			nodeIndex++;
			
		}
		
		
	}
	private boolean conpareCharArray(char[] array1,char[] array2)
	{
		if (array1.length != array2.length)
			return false;
		for(int i=0;i<array1.length;i++)
		{
			if(array1[i]!= array2[i])
				return false;
		}
		return true;
	}
	
	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		this.close();
	}
	
	public void close() throws IOException
	{
		this.reader.close();
		this.fis.close();
	}

}
